package com.flute.tools.util.collection;

import java.util.ArrayList;
import java.util.List;

public class BottomList<T extends IWeightable> {
	private List<T> list;
	private int capacity;
	private double max;

	public BottomList() {
		capacity = Integer.MAX_VALUE;
		this.list = new ArrayList<T>();
	}

	public BottomList(int capacity) {
		this.capacity = capacity;
		this.list = new ArrayList<T>();
	}

	public void add(T t) {
		if (list.size() < capacity) {
			insertToList(t);
			max = list.get(list.size() - 1).getWeight();
		} else if (t.getWeight() < max) {
			insertToList(t);
			list.remove(list.size() - 1);
			max = list.get(list.size() - 1).getWeight();
		}
	}

	public List<T> getList() {
		return list;
	}

	public void setList(List<T> list) {
		this.list = list;
	}

	public int size() {
		return list.size();
	}

	private void insertToList(T weightable) {
		int start = 0;
		int end = list.size();
		if (list.size() == 0) {
			list.add(weightable);
		} else {
			loop: while (true) {
				int middle = (start + end) / 2;
				if (list.get(middle).getWeight() < weightable.getWeight()) {
					if (start == middle) {
						list.add(end, weightable);
						break;
					} else {
						start = middle;
					}
				} else if (list.get(middle).getWeight() > weightable
						.getWeight()) {
					if (end == middle) {
						list.add(start, weightable);
						break;
					} else {
						end = middle;
					}
				} else if (list.get(middle).getWeight() == weightable
						.getWeight()) {
					for (int i = middle + 1; i < list.size(); i++) {
						if (list.get(i).getWeight() > weightable.getWeight()) {
							if (i > 0) {
								list.add(i - 1, weightable);
							} else {
								list.add(weightable);
							}
							break loop;
						}
					}
					list.add(weightable);
					break;
				}
			}
		}
	}
}
